package com.xiaoshuidi.cloud.module.iot.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.xiaoshuidi.cloud.module.iot.common.ResultModel;
import com.xiaoshuidi.cloud.module.iot.dal.model.AccessTokenRequestWrapperModel;
import com.xiaoshuidi.cloud.module.iot.dal.model.AccessTokenResponseModel;
import com.xiaoshuidi.cloud.module.iot.dal.model.AccessTokenResponseWrapperModel;
import com.xiaoshuidi.cloud.module.iot.dal.pojo.TbAccountDo;
import com.xiaoshuidi.cloud.module.iot.dal.repository.TbAccountRepository;
import com.xiaoshuidi.cloud.module.iot.enums.ErrorCodeEnum;
import com.xiaoshuidi.cloud.module.iot.enums.RedisTypeEnum;
import com.xiaoshuidi.cloud.module.iot.service.CacheService;
import com.xiaoshuidi.cloud.module.iot.service.LocalAccessTokenServcie;
import com.xiaoshuidi.cloud.module.iot.service.ThirdInstanceFactory;
import com.xiaoshuidi.cloud.module.iot.service.ThirdInstanceService;
import net.sf.cglib.beans.BeanCopier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author Sky
 * create 2019/04/11
 * email sky.li@ixiaoshuidi.com
 **/
@Service
public class LocalAccessTokenServiceImpl implements LocalAccessTokenServcie {

    private final static Logger LOGGER = LoggerFactory.getLogger(LocalAccessTokenServiceImpl.class);

    @Autowired
    private CacheService cacheService;

    @Autowired
    private TbAccountRepository tbAccountDataAccess;

    /**
     * 获取access_token
     *
     * @return
     */
    @Override
    public ResultModel<AccessTokenResponseWrapperModel> getAccessToken(AccessTokenRequestWrapperModel accessTokenRequestWrapperModel) throws Exception {
        ResultModel<AccessTokenResponseWrapperModel> resultModel = null;
        AccessTokenResponseWrapperModel accessTokenResponseWrapperModel = new AccessTokenResponseWrapperModel();
        //品牌
        String brand = accessTokenRequestWrapperModel.getBrand();
        //第三方appId
        String appId = null;
        //第三方appKey
        String appKey = null;
        //登录手机号
        String phone = null;
        //水滴IOT,第三方appid,appkey唯一标志
        String apiNo = accessTokenRequestWrapperModel.getApiNo();
        if (StrUtil.isNotBlank(apiNo)) {
            TbAccountDo tbAccountModel = tbAccountDataAccess.getThirdApiByApiNo(apiNo);
            if (tbAccountModel != null) {
                brand = tbAccountModel.getBrandNo();
                appId = tbAccountModel.getLoginName();
                appKey = tbAccountModel.getLoginKey();
                phone = tbAccountModel.getLoginMobile();
            }
        } else {
            //获取第三方appid(账号)
            appId = accessTokenRequestWrapperModel.getAppId();
            //获取第三方appKey(密码)
            appKey = accessTokenRequestWrapperModel.getAppKey();
            phone = accessTokenRequestWrapperModel.getPhone();
        }
        LOGGER.info("appId====" + appId + "  appKey=====" + appKey);
        if (StrUtil.isBlank(appId) || StrUtil.isBlank(appKey)) {
            resultModel = ResultModel.createFail(ErrorCodeEnum.INVALID_API_NO.getCode(), ErrorCodeEnum.INVALID_API_NO.getMsg());
        } else {
            //从缓存中获取access_token
            String cacheKey = RedisTypeEnum.SDIOT_ACCESS_TOKEN.getCode() + appId + appKey;
            String accessToknJson = cacheService.getString(cacheKey);
            //token已经过期
            if (StrUtil.isBlank(accessToknJson)) {
                //从第三方重新获取access_token
                //获取对应第三方获取实例
                accessTokenRequestWrapperModel.setBrand(brand);
                accessTokenRequestWrapperModel.setAppId(appId);
                accessTokenRequestWrapperModel.setAppKey(appKey);
                accessTokenRequestWrapperModel.setPhone(phone);
                //获取和刷新token公共方法调用
                resultModel = this.getAndRefreshTokenMethod(accessTokenRequestWrapperModel);
                LOGGER.info("getAccessToken->获取和刷新token公共方法调用结果：{}", JSONObject.toJSONString(resultModel));
            } else {
                accessTokenResponseWrapperModel = JSONObject.parseObject(accessToknJson, AccessTokenResponseWrapperModel.class);
                accessTokenResponseWrapperModel.setExpireTime(cacheService.getExpire(cacheKey));
                accessTokenResponseWrapperModel.setAppId(appId);
                accessTokenResponseWrapperModel.setAppKey(appKey);
                resultModel = ResultModel.createSuccess(accessTokenResponseWrapperModel);
            }
        }
        return resultModel;
    }

    /**
     * 获取和刷新token 公用方法抽取
     *
     * @param accessTokenRequestWrapperModel
     * @return
     */
    public ResultModel<AccessTokenResponseWrapperModel> getAndRefreshTokenMethod(AccessTokenRequestWrapperModel accessTokenRequestWrapperModel) throws Exception {
        ResultModel<AccessTokenResponseWrapperModel> resultModel = null;
        AccessTokenResponseWrapperModel accessTokenResponseWrapperModel = new AccessTokenResponseWrapperModel();
        String brand = accessTokenRequestWrapperModel.getBrand();
        String appId = accessTokenRequestWrapperModel.getAppId();
        String appKey = accessTokenRequestWrapperModel.getAppKey();
        String cacheKey = RedisTypeEnum.SDIOT_ACCESS_TOKEN.getCode() + appId + appKey;
        //获取对应第三方获取实例
        ThirdInstanceService accessTokenService = ThirdInstanceFactory.produce(brand);
        AccessTokenResponseModel accessTokenResponseModel = accessTokenService.getAccessToken(accessTokenRequestWrapperModel);
        if (accessTokenResponseModel != null) {
            BeanCopier.create(AccessTokenResponseModel.class, AccessTokenResponseWrapperModel.class, false).copy(accessTokenResponseModel, accessTokenResponseWrapperModel, null);
            //获取token，并保存到缓存中。
            String cacheComment = JSONObject.toJSONString(accessTokenResponseModel);
            LOGGER.info("cacheComment->获取token:{}", cacheComment);
            cacheService.putString(cacheKey, cacheComment, (int) accessTokenResponseModel.getExpireTime());
            LOGGER.info("getAccessToken和refreshAccessToken->获取token，并保存到缓存中,保存信息内容:{}", cacheComment);
            accessTokenResponseWrapperModel.setAppId(appId);
            accessTokenResponseWrapperModel.setAppKey(appKey);
            resultModel = ResultModel.createSuccess(accessTokenResponseWrapperModel);
        } else {
            resultModel = ResultModel.createFail(ErrorCodeEnum.BRAND_PARTY_ACCESSTOKEN_EXCEPTION.getCode(), ErrorCodeEnum.BRAND_PARTY_ACCESSTOKEN_EXCEPTION.getMsg());
        }
        return resultModel;
    }


    /**
     * 刷新access_token
     *
     * @param accessTokenRequestWrapperModel
     * @return
     * @throws Exception
     */
    @Override
    public ResultModel<AccessTokenResponseWrapperModel> refreshAccessToken(AccessTokenRequestWrapperModel accessTokenRequestWrapperModel) throws Exception {
        ResultModel<AccessTokenResponseWrapperModel> resultModel = null;
        if (StrUtil.isNotBlank(accessTokenRequestWrapperModel.getApiNo())) {
            TbAccountDo tbAccountDo = tbAccountDataAccess.getThirdApiByApiNo(accessTokenRequestWrapperModel.getApiNo());
            if (tbAccountDo != null) {
                accessTokenRequestWrapperModel.setAppId(tbAccountDo.getLoginName());
                accessTokenRequestWrapperModel.setAppKey(tbAccountDo.getLoginKey());
                accessTokenRequestWrapperModel.setBrand(tbAccountDo.getBrandNo());
                accessTokenRequestWrapperModel.setPhone(tbAccountDo.getLoginMobile());
            } else {
                resultModel = ResultModel.createFail(ErrorCodeEnum.INVALID_API_NO.getCode(), ErrorCodeEnum.INVALID_API_NO.getMsg());
                return resultModel;
            }
        }
        resultModel = this.getAndRefreshTokenMethod(accessTokenRequestWrapperModel);
        LOGGER.info("refreshAccessToken->获取和刷新token公共方法调用结果：{}", JSONObject.toJSONString(resultModel));
        return resultModel;
    }


}
